package com.hyt.it.ogt.kq.service.bm.api.gov;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hyt.common.apiInfor.ApiResponse;
import com.hyt.it.ogt.kq.common.bm.enums.BmProjectAllowRefundEnum;
import com.hyt.it.ogt.kq.common.bm.enums.BmProjectNeedPayEnum;
import com.hyt.it.ogt.kq.common.bm.enums.BmProjectVerifyEnum;
import com.hyt.it.ogt.kq.common.bm.utils.Constant;
import com.hyt.it.ogt.kq.common.config.ConfigManager;
import com.hyt.it.ogt.kq.common.gov.utils.tree.Tree;
import com.hyt.it.ogt.kq.service.bm.api.ApiBaseController;
import com.hyt.it.ogt.kq.service.bm.mapper.ProjectSubjectMapper;
import com.hyt.it.ogt.kq.service.bm.model.entity.Project;
import com.hyt.it.ogt.kq.service.bm.model.entity.ProjectExam;
import com.hyt.it.ogt.kq.service.bm.model.entity.ProjectSubject;
import com.hyt.it.ogt.kq.service.bm.model.vo.SubjectStatVo;
import com.hyt.it.ogt.kq.service.bm.service.IApiFailService;
import com.hyt.it.ogt.kq.service.bm.service.IProjectExamService;
import com.hyt.it.ogt.kq.service.bm.service.IProjectService;
import com.hyt.it.ogt.kq.service.bm.service.IProjectSubjectService;
import com.hyt.it.ogt.kq.service.model.param.ApiFail;
import com.hyt.it.ogt.kq.service.model.vo.candidateSubject.BmTaskData;
import com.hyt.it.ogt.kq.service.model.vo.candidateSubject.OverviewBmSubjectVO;
import com.hyt.it.ogt.kq.service.model.vo.candidateSubject.OverviewBmVO;
import com.hyt.it.ogt.kq.service.model.vo.wechat.PushExamNotifyDTO;
import com.hyt.loginfo.model.User;
import com.hyt.loginfo.service.IBaseLoginService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiOperationSort;
import io.swagger.annotations.ApiSort;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 政企考务服务调用的接口
 * </p>
 *
 * @author liuq
 * @since 2021-08-02
 */
@RestController
@Api(tags = "22.政企考务服务调用的接口", value = "政企考务服务调用的接口")
@ApiSort(value = 22)
@RequestMapping("/api/gov")
public class KwGovApi extends ApiBaseController {

    private static final String SERVER_NAME = "it-ogt-kw-gov";
    @Autowired
    private IApiFailService iApiFailService;
    @Autowired
    private IProjectExamService iProjectExamService;
    @Autowired
    private IProjectSubjectService iProjectSubjectService;
    @Autowired
    private ConfigManager configManager;
    @Autowired
    private IProjectService iProjectService;
    @Resource
    private ProjectSubjectMapper projectSubjectMapper;
    @Autowired
    private IBaseLoginService baseLoginService;

    @ApiOperation(
            value = "查询api调用失败的参数",
            notes = "14001:成功"
    )
    @ApiOperationSort(value = 1)
    @RequestMapping(value = "/apifail/list", method = RequestMethod.GET)
    public ApiResponse<List<ApiFail>> apiFailList(@RequestParam("api") String api) {
        List<ApiFail> apiFailList = iApiFailService.lambdaQuery()
                .eq(ApiFail::getServerName, SERVER_NAME)
                .eq(ApiFail::getApi, api)
                .eq(ApiFail::getStatus, false)
                .orderByAsc(ApiFail::getId)
                .list();
        if (apiFailList != null && !apiFailList.isEmpty()) {
            iApiFailService.lambdaUpdate()
                    .eq(ApiFail::getServerName, SERVER_NAME)
                    .eq(ApiFail::getApi, api)
                    .set(ApiFail::getStatus, true);
        }
        return ApiResponse.<List<ApiFail>>builder()
                .code(Constant.RESPONSE_CODE_SUCCESS)
                .data(apiFailList)
                .build();
    }

    @ApiOperation(
            value = "删除api调用失败的记录",
            notes = "14001:成功"
    )
    @ApiOperationSort(value = 2)
    @RequestMapping(value = "/apifail/delete", method = RequestMethod.DELETE)
    public ApiResponse<Object> apiFailDelete(@RequestParam("idArrayJson") String idArrayJson) {
        List<String> idList = JSONArray.parseArray(idArrayJson, String.class);
        if (idList != null && !idList.isEmpty()) {
            iApiFailService.removeByIds(idList);
        }
        return ApiResponse.builder()
                .code(Constant.RESPONSE_CODE_SUCCESS)
                .build();
    }

    @ApiOperation(
            value = "查询任务总览报名管理科目VO",
            notes = "14001:成功"
    )
    @ApiOperationSort(value = 3)
    @RequestMapping(value = "/get/overview", method = RequestMethod.GET)
    public ApiResponse<OverviewBmVO> getOverviewBmVO(@RequestParam("projectID") String projectID) {
        String deptId = "";
        Project project = iProjectService.getById(projectID);
        if (0 == project.getIsOpen()) {
            deptId = getDeptId();
        }
        List<String> permissionList = new ArrayList<>();
        List<SubjectStatVo> subjectList = projectSubjectMapper.statSubjectByProjectId(projectID, permissionList, null, deptId);
        OverviewBmVO vo = new OverviewBmVO();
        vo.setBeginTime(project.getBeginTime());
        vo.setEndTime(project.getEndTime());
        vo.setBmUrl(project.getAddress());
        vo.setQrCodeUrl(project.getQrCodeUrl());
        vo.setGlUrl(configManager.getBmglDetailAddress() + projectID);
        List<OverviewBmSubjectVO> subjects = new ArrayList<>();
        if (CollUtil.isNotEmpty(subjectList)) {
            for (int i = 0; i < subjectList.size(); i++) {
                SubjectStatVo subjectStatVo = subjectList.get(i);
                // 首先看科目需不需要缴费
                ProjectSubject projectSubject = iProjectSubjectService.queryBySubjectId(projectID, subjectStatVo.getSubjectId());
                if (null == projectSubject) {
                    continue;
                }
                OverviewBmSubjectVO overviewBmSubjectVO = new OverviewBmSubjectVO();
                overviewBmSubjectVO.setName(subjectStatVo.getSubjectName());
                // 如果是项目需要缴费
                if (project.getIsPay().intValue() == 1) {
                    // 如果科目需要缴费
                    if (projectSubject.getIsPay() == 1) {
                        overviewBmSubjectVO.setCount(String.valueOf(subjectStatVo.getPayNum()));
                    } else {
                        // 如果不需要缴费，看项目需不需要审核
                        if (project.getIsVerify().intValue() == 1) {
                            overviewBmSubjectVO.setCount(String.valueOf(subjectStatVo.getAuditNum()));
                        } else {
                            overviewBmSubjectVO.setCount(String.valueOf(subjectStatVo.getApplyNum()));
                        }
                    }
                } else {
                    // 如果不需要缴费，看项目需不需要审核
                    if (project.getIsVerify().intValue() == 1) {
                        overviewBmSubjectVO.setCount(String.valueOf(subjectStatVo.getAuditNum()));
                    } else {
                        overviewBmSubjectVO.setCount(String.valueOf(subjectStatVo.getApplyNum()));
                    }
                }
                subjects.add(overviewBmSubjectVO);
            }
        }
        vo.setSubjects(subjects);
        return ApiResponse.<OverviewBmVO>builder()
                .code(Constant.RESPONSE_CODE_SUCCESS)
                .data(vo)
                .build();
    }

    @ApiOperation(
            value = "查询云考试报名任务列表",
            notes = "14001:成功"
    )
    @ApiOperationSort(value = 3)
    @RequestMapping(value = "/project/tree", method = RequestMethod.GET)
    public ApiResponse<List<Tree>> projectTree() {
        String officeId = getOfficeId();
        Set<String> deptIds = getDeptIds();
        List<Project> list = iProjectService.queryExamProject(officeId, deptIds);
        List<Project> listTemp = new ArrayList<>();
        for (Project bmProject : list) {
            // 如果报名不需要审核, 不需要缴费
            if (BmProjectVerifyEnum.UNVERIFY.getVerifyStatus().equals(bmProject.getIsVerify()) && BmProjectNeedPayEnum.UNPAY.getPayStatus().equals(bmProject.getIsPay())) {
                if (null != bmProject.getEndTime() && bmProject.getEndTime().isAfter(LocalDateTime.now())) {
                    continue;
                }
            }
            // 如果报名不需要审核, 需要缴费
            if (BmProjectVerifyEnum.UNVERIFY.getVerifyStatus().equals(bmProject.getIsVerify()) && BmProjectNeedPayEnum.PAY.getPayStatus().equals(bmProject.getIsPay())) {
                // 如果允许退费
                if (BmProjectAllowRefundEnum.ALLOW.getRefundStatus().equals(bmProject.getIsRefund())) {
                    if (null != bmProject.getRefuseTime() && bmProject.getRefuseTime().isAfter(LocalDateTime.now())) {
                        continue;
                    }
                }
                // 如果不允许退费
                if (BmProjectAllowRefundEnum.UNALLOW.getRefundStatus().equals(bmProject.getIsRefund())) {
                    if (null != bmProject.getPayEndTime() && bmProject.getPayEndTime().isAfter(LocalDateTime.now())) {
                        continue;
                    }
                }
            }
            // 如果报名需要审核, 需要缴费
            if (BmProjectVerifyEnum.VERIFY.getVerifyStatus().equals(bmProject.getIsVerify()) && BmProjectNeedPayEnum.PAY.getPayStatus().equals(bmProject.getIsPay())) {
                // 如果允许退费
                if (BmProjectAllowRefundEnum.ALLOW.getRefundStatus().equals(bmProject.getIsRefund())) {
                    if (null != bmProject.getRefuseTime() && bmProject.getRefuseTime().isAfter(LocalDateTime.now())) {
                        continue;
                    }
                }
                // 如果不允许退费
                if (BmProjectAllowRefundEnum.UNALLOW.getRefundStatus().equals(bmProject.getIsRefund())) {
                    if (null != bmProject.getPayEndTime() && bmProject.getPayEndTime().isAfter(LocalDateTime.now())) {
                        continue;
                    }
                }
            }
            // 如果报名需要审核, 不需要缴费
            if (BmProjectVerifyEnum.VERIFY.getVerifyStatus().equals(bmProject.getIsVerify()) && BmProjectNeedPayEnum.UNPAY.getPayStatus().equals(bmProject.getIsPay())) {
                if (null != bmProject.getAuditEndTime() && bmProject.getAuditEndTime().isAfter(LocalDateTime.now())) {
                    continue;
                }
                if (null == bmProject.getAuditEndTime() && bmProject.getEndTime().isAfter(LocalDateTime.now())) {
                    continue;
                }
            }
            listTemp.add(bmProject);
        }
        List<Tree> treeList = new ArrayList<Tree>();
        if (listTemp != null && listTemp.size() > 0) {
            for (int i = 0; i < listTemp.size(); i++) {
                Tree tree = new Tree();
                tree.setValue(listTemp.get(i).getId());
                tree.setLabel(listTemp.get(i).getProjectName());
                treeList.add(tree);
            }
        }
        return ApiResponse.<List<Tree>>builder()
                .code(Constant.RESPONSE_CODE_SUCCESS)
                .data(treeList)
                .build();
    }

    @ApiOperation(
            value = "政企考务云考试报名绑定",
            notes = "14001:成功"
    )
    @ApiOperationSort(value = 4)
    @RequestMapping(value = "/bind", method = RequestMethod.POST)
    public ApiResponse<BmTaskData> bind(@RequestParam("taskId") String taskId, @RequestParam("projectId") String projectId) {
        logger.info("# 考务绑定报名 taskId:{}, projectId:{}", taskId, projectId);
        User user = baseLoginService.getSysUser();
        if (null == user || StringUtils.isEmpty(user.getId())) {
            return ApiResponse.<BmTaskData>builder().code(Constant.RESPONSE_CODE_14077).build();
        }
        try {
            BmTaskData bmTaskData = iProjectExamService.bindProjectExam(user.getId(), taskId, projectId);
            bmTaskData.setOfficeId(user.getOfficeid());
            return ApiResponse.<BmTaskData>builder()
                    .code(Constant.RESPONSE_CODE_SUCCESS)
                    .data(bmTaskData)
                    .build();
        } catch (Exception ex) {
            ex.printStackTrace();
            return ApiResponse.<BmTaskData>builder()
                    .code(Constant.RESPONSE_CODE_14077)
                    .build();
        }
    }

    @ApiOperation(value = "政企考务云考试报名解绑", notes = "14001:成功")
    @ApiOperationSort(value = 5)
    @RequestMapping(value = "/unbind", method = RequestMethod.POST)
    public ApiResponse<Object> unbind(@RequestParam("taskId") String taskId, @RequestParam("projectId") String projectId) {
        //政企考务云考试报名解绑
        QueryWrapper<ProjectExam> wrapper = new QueryWrapper<ProjectExam>();
        wrapper.eq("project_id", projectId);
        wrapper.eq("exam_id", taskId);
        iProjectExamService.remove(wrapper);
        return ApiResponse.builder()
                .code(Constant.RESPONSE_CODE_SUCCESS)
                .build();
    }

    @ApiOperation(value = "5.1.16 获取报名项目地址", notes = "14001:成功,14021:查询失败，异常")
    @ApiOperationSort(value = 16)
    @RequestMapping(value = "/loadBmglAddress", method = RequestMethod.GET)
    public Object loadBmglAddress() {
        try {
            return ApiResponse.builder().code(Constant.RESPONSE_CODE_SUCCESS).data(configManager.getBmglAddress()).build();
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResponse.builder().code(Constant.RESPONSE_CODE_14021).data(e.getMessage().toString()).build();
        }
    }

    /**
     * 用户场景	考务管理员推送考试安排通知
     * 功能描述	系统将考试安排相关字段信息推送到小程序及微信服务通知中
     * 当推送超过设定的用户数，将会截取配置的数量进行推送
     *
     * @param pushExamNotifyDTOS
     * @return 推送的用户数
     */
    @ApiOperation(value = "22.2.1 考务管理员推送考试安排通知", notes = "14001：成功；31222101：考务管理员推送考试安排通知异常；31222102：缺少所需的参数；")
    @ApiOperationSort(value = 6)
    @RequestMapping(value = "/pushExamNotify", method = RequestMethod.POST)
    public ApiResponse<Long> pushExamNotify(@RequestBody List<PushExamNotifyDTO> pushExamNotifyDTOS) {
        try {
            return ApiResponse.<Long>builder()
                    .code(Constant.RESPONSE_CODE_SUCCESS)
                    .data(iProjectService.pushExamNotify(pushExamNotifyDTOS))
                    .build();
        } catch (Exception e) {
            logger.error("# 考务管理员推送考试安排通知异常：", e);
            return ApiResponse.<Long>builder()
                    .code(Constant.RESPONSE_CODE_31222101)
                    .build();
        }
    }
}
